#ifndef _FPDFEMB_3RD_DRM_H_
#define _FPDFEMB_3RD_DRM_H_


typedef void*  FPDFEMB_DICTIONARY;
typedef void*  FPDFEMB_LPVOID;
typedef void* FPDFEMB_OUTPUT;
typedef unsigned long  FPDFEMB_DWORD;
typedef unsigned char const*	 FPDFEMB_LPCBYTE;
typedef const char* 	FPDFEMB_LPCSTR;

/**
 * @name PDF document permissions, according to PDF Reference, Table 3.20.
 * 1-2 bits must be zero, 7-8, 13-32 bits must be 1.
 */
/*@{*/

/**
 * @brief bit 3.
 * - (Revision 2) Print the document.
 * - (Revision 3 or greater) Print the document (possibly not at the highest
 * quality level, depending on whether bit 12 is also set).
 */
#define FPDFPERM_PRINT			0x0004
/**
 * @brief bit 4. Modify the contents of the document by operations other than
 * those controlled by bits 6, 9, and 11.
 */
#define FPDFPERM_MODIFY			0x0008
/**
 * @brief bit 5.
 * - (Revision 2) Copy or otherwise extract text and graphics from the
 * document, including extracting text and graphics (in support of accessibility
 * to users with disabilities or for other purposes).
 * - (Revision 3 or greater) Copy or otherwise extract text and graphics
 * from the document by operations other than that controlled by bit 10.
 */
#define FPDFPERM_EXTRACT		0x0010
/**
 * @brief bit 6. Add or modify text annotations, fill in interactive form fields, and,
 * if bit 4 is also set, create or modify interactive form fields (including signature fields).
 */
#define FPDFPERM_ANNOT_FORM		0x0020
/**
 * @brief bit 9. (Revision 3 or greater) Fill in existing interactive form fields (including signature fields),
 * even if bit 6 is clear.
 */
#define FPDFPERM_FILL_FORM		0x0100
/**
 * @brief bit 10. (Revision 3 or greater) Extract text and graphics (in support of accessibility
 * to users with disabilities or for other purposes).
 */
#define FPDFPERM_EXTRACT_ACCESS	0x0200
/**
 * @brief bit 11. (Revision 3 or greater) Assemble the document (insert, rotate, or delete pages
 * and create bookmarks or thumbnail images), even if bit 4 is clear.
 */
#define FPDFPERM_ASSEMBLE		0x0400
/**
 * @brief bit 12. (Revision 3 or greater) Print the document to a representation from
 * which a faithful digital copy of the PDF content could be generated.
 * When this bit is clear (and bit 3 is set), printing is limited to a low-level
 * representation of the appearance, possibly of degraded quality.
 * (See implementation note 25 in Appendix H.)
 */
#define FPDFPERM_PRINT_HIGH		0x0800

#define FXCIPHER_RC4	1	// RC4 encrytion algorithm
#define FXCIPHER_AES		2	// AES encrytion algorithm


#ifdef __cplusplus
extern "C" {
#endif

struct FPDFEMB_SecurityHandler {
	/**
	 * Initialization. The handler should typically keep record of parser pointer, and
	 * process data in the encryption dictionary.
	 *
	 *@param[in] pThis        Pointer to this FPDFEMB_SecutityHandler structure
	 * @param[in] pParser			The PDF parser.
	 * @param[in] pEncryptDict		The Encrypt dictionary.
	 * @return Non-zero means initializing successfully, otherwise failed.
	 */
	FPDFEMB_BOOL (*EmbOnInit)(struct FPDFEMB_SecurityHandler* pThis,
			FPDFEMB_DOCUMENT pParser, FPDFEMB_DICTIONARY pEncryptDict);

	/** Get permission settings of the document.
	 * @param[in] pThis        Pointer to this FPDFEMB_SecutityHandler structure
	 *@return 	See above  FPDFPERM_xxx constants
	 */
	FPDFEMB_DWORD (*EmbGetPermissions)(struct FPDFEMB_SecurityHandler* pThis);

	/** Check whether the current user is owner of the document.
	 * @param[in] pThis        Pointer to this FPDFEMB_SecutityHandler structure
	 */
	FPDFEMB_BOOL (*EmbIsOwner)(struct FPDFEMB_SecurityHandler* pThis);

	/** Check if document metadata needs to be encrypted.
	 * @param[in] pThis        Pointer to this FPDFEMB_SecutityHandler structure
	 */
	FPDFEMB_BOOL (*EmbIsMetadataEncrypted)(
			struct FPDFEMB_SecurityHandler* pThis);

	/**
	 * Get encryption information including standard algorithm and key.
	 *
	 *@param[in] pThis       		Pointer to this FPDFEMB_SecutityHandler structure
	 * @param[out] cipher			Receives cipher identifier (FXCIPHER_NONE, FXCIPHER_RC4 or FXCIPHER_AES).
	 * @param[out] buffer			Receives a pointer to the key buffer.
	 * @param[out] keylen			Receives number of bytes in the key.
	 * @return TRUE if successful. FALSE if no standard key info is provided or failure.
	 */
	FPDFEMB_BOOL (*EmbGetCryptInfo)(struct FPDFEMB_SecurityHandler* pThis,
			int* cipher, FPDFEMB_LPCBYTE* buffer, int* keylen);

	/**
	 * Create a crypto handler that can do the real encryption/decryption work.
	 * @param[in] pThis        Pointer to this FPDFEMB_SecutityHandler structure
	 * @return Pointer to FPDFEMB_CryptoHandler structure.
	 */
	struct FPDFEMB_CryptoHandler* (*EmbGetCryptoHandler)(
			struct FPDFEMB_SecurityHandler* pThis);

	void *user; /**< A user pointer, used by the application. */
};

struct FPDFEMB_CryptoHandler {

	/**
	 * Initialize the crypto handler with a security handler, and the encrypt dictionary data.
	 * This function can be optional if the implementation do initialization in other way.
	 *
	 *@param[in]  pThis					Pointer to this FPDFMEB_CryptoHandler.
	 * @param[in] pEncryptDict		The Encrypt dictionary.
	 * @param[in] pSecurityHandler	The security handler.
	 * @return Non-zero means success, otherwise failure.
	 */
	FPDFEMB_BOOL (*EmbInit)(struct FPDFEMB_CryptoHandler* pThis,
			FPDFEMB_DICTIONARY pEncryptDict,
			struct FPDFEMB_SecurityHandler* pSecurityHandler);

	/**
	 * Start a decryption process. If decryption is for some indirect object, object number and generation
	 * number are provided.
	 * Implementation can create a context and return pointer to the context.
	 *
	 *@@param[in]  pThis		Pointer to this FPDFMEB_CryptoHandler.
	 * @param[in] objnum		The indirect object number.
	 * @param[in] gennum		The indirect object generation number.
	 * @return A decrypt context.
	 */
	FPDFEMB_LPVOID (*EmbDecryptStart)(struct FPDFEMB_CryptoHandler* pThis,
			FPDFEMB_DWORD objnum, FPDFEMB_DWORD gennum);

	/**
	 * Finish a decryption process.
	 * If decryption context is used, implementation should destroy it.
	 * If there is any left-over data, they should be added to the destination buffer.
	 *
	 *@@param[in]  pThis			Pointer to this FPDFMEB_CryptoHandler.
	 * @param[in] context			The decrypt context.
	 * @param[out] output			Use FPDFEMB_OutputBinaryBuf(...)  to output the decrypted data
	 * 											for FPDFEMB_OUTPUT object to call
	 * @return Non-zero means success, otherwise failure.
	 */
	FPDFEMB_BOOL (*EmbDecryptFinish)(struct FPDFEMB_CryptoHandler* pThis,
			FPDFEMB_LPVOID context, FPDFEMB_OUTPUT ouput);

	/**
	 * Decrypt some source data in a stream.
	 * The "context" parameter is the same as returned by DecryptStart() function.
	 * Implementation should append the decrypted data (if any) to the dest_buf dynamic array.
	 *
	 *@@param[in]  pThis		Pointer to this FPDFMEB_CryptoHandler.
	 * @param[in] context		The decrypt context.
	 * @param[in] src_buf		The encrypted source data.
	 * @param[in] src_size		The size in bytes of the source data.
	 * @param[out] output		Use FPDFEMB_OutputBinaryBuf(...)  to output the decrypted data
	 * 										for FPDFEMB_OUTPUT object to call
	 * @return Non-zero means success, otherwise failure.
	 */
	FPDFEMB_BOOL (*EmbDecryptBlock)(struct FPDFEMB_CryptoHandler* pThis,
			FPDFEMB_LPVOID context, FPDFEMB_LPCBYTE src_buf,
			FPDFEMB_DWORD src_size, FPDFEMB_OUTPUT ouput);

	void *user;/**< A user pointer, used by the application. */
};

/**
 *Output the binary data to  FPDFEMB_OUTPUT object.
 *
 *@pOutput[out] 		Receives the binary data.
 *@data[in]				The binary data.
 *@len[in]					The size in bytes of the data.
 */
void		FPDFEMB_OutputBinaryBuf(FPDFEMB_OUTPUT pOutput, FPDFEMB_LPCBYTE data, int len);

/**
 * Register SecurtyHandler
 *
 * @param[in] name	The name of SecurityHandler.
 *  @return Error code, or FDPFERR_SUCCESS for success.
 */

FPDFEMB_RESULT FPDFEMB_RegisterSecurityHandler(FPDFEMB_LPCSTR name, struct FPDFEMB_SecurityHandler* SHandler);
/**
 *  Unregister SecurtyHandler
 *
 * @param[in] name	The name of SecurityHandler.
 */
void FPDFEMB_UnRegisterSecurityHandler(FPDFEMB_LPCSTR name);


/**
 * Get a Standard CryptoHandler
 * If you don't want to customize the funtions of FPDFEMB_CryptoHandler,
 *	you can use this function to get a standard CryptoHandler.
 *	128-bit: keylen = 16;	256-bit: keylen = 32
 *
 * @param[in]  Cipher identifier (FXCIPHER_NONE, FXCIPHER_RC4 or FXCIPHER_AES).
 * @param[in]	Key			Key for CryptoHandler
 * @param[in]	kenlen		Length of the key
 * @return Pointer to Standard CryptoHandler
 */
struct FPDFEMB_CryptoHandler*		GetStandardCryptoHandler(int cipher, FPDFEMB_LPCBYTE key, int keylen);


/**
 * Get the string data for the element specified by key.
 *
  * @param[in] pDict		The input dictionary pointer
 * @param[in] key		The input key string.
 * @return A byte string for the specified element.
 */
FPDFEMB_LPCSTR FPDFEMB_DictGetString(FPDFEMB_DICTIONARY pDict, FPDFEMB_LPCSTR key);

/**
 * Get the integer data for the element specified by key.
 *
 * @param[in] pDict		The input dictionary pointer
 * @param[in] key			The input key string.
 * @return An integer value for the specified element.
 */
int FPDFEMB_DictGetInteger( FPDFEMB_DICTIONARY pDict, FPDFEMB_LPCSTR key);

/**
 * Get the boolean data for the element specified by key with a default boolean value.
 *
  * @param[in] pDict		The input dictionary pointer
 * @param[in] key			The input key string.
 * @return A boolean value for the specified element.
 */
FPDFEMB_BOOL FPDFEMB_DictGetBoolean(FPDFEMB_DICTIONARY pDict, FPDFEMB_LPCSTR key);

/**
 * Whether the element specified by key exist.
 *
  * @param[in] pDict		The input dictionary pointer
 * @param[in] key			The input key string.
 * @return Non-zero means exist, otherwise not.
 */
FPDFEMB_BOOL FPDFEMB_DictKeyExist(FPDFEMB_DICTIONARY pDict, FPDFEMB_LPCSTR key);

#ifdef __cplusplus
};
#endif

#endif// _FPDFEMB_3RD_DRM_H_





















